Programmable logic devices such as field programmable gate arrays (FPGAs) and complex programmable logic devices (CPLDs) allow a designer to avoid the expense of constructing an ASIC to implement a desired function. Moreover, a user may update a system by reprogramming its embedded programmable logic device rather than go through the expense of a new hardware design. Thus, programmable logic devices (PLDs) are a common design component. To allow communication with other components in a system, PLDs will typically include input/output (I/O) ports supporting common communication protocols such as Serial Peripheral Interface (SPI) or Inter-Integrated Circuit (I2C). As known in the integrated circuit arts, SPI and I2C are conventional serial bus protocols for serial data communication between integrated circuits (and intra-chip in some implementations).
In both protocols, data is shifted into and out of the PLD according to a master clock supplied by a master device. For example, the master device may be a host PC that needs to read some information from an embedded memory in the PLD. The desired data is then shifted out of the PLD one bit at a time responsive to cycles of the master clock. In general, it takes some time for a PLD to respond to such a memory read request. However, the port protocols such as SPI and I2C require data to be shifted out at each clock cycle. Thus, it is conventional for the PLD to be configured such that it first shifts out dummy bits (having don't care values) prior to shifting out the actual data. For example, the master device will expect the actual data at some pre-agreed-upon clock cycle such that a predetermined number of dummy bytes are first provided by the PLD. The fixed amount of dummy data that is shifted out must accommodate the worst case scenario such that in many situations some portion of the dummy bytes are unnecessary. Such a fixed amount of dummy data is inefficient and makes the various read commands inconsistent.
Accordingly, there is a need in the art for an improved command execution protocol for synchronous data reads.